Kontrola danych w formularzu
Opublikowano: 2009-07-28 , wyświetlono: 8061
Prawie każdy wypełniał jakiś formularz na stronie www. Klikamy na przycisk Submit i czekamy na komunikat o poprawności przesłanych danych. Czekamy ... , a tu niespodzianka okazało się, że błędnie podaliśmy jakąś informacje i sktypt poinformował nas o błędzie we wprowadzonych danych. Wracamy na poprzednią stronę, uzupełniamy to co trzeba i już z pewną nieśmiałością czekamy na odpowiedź serwera.
Ten sam ból mają twórcy skryptów, np. w jakim formacie użytkownik wprowadzi datę, może rrrr/mm/dd, a może dd/mm/rr.
Mając na uwadze te problemy, które wynikły w mojej praktyce stworzyłem klasę JavaScript do kontroli danych wprowadzonych w formularzu.
Załóżmy, że na stronie www mam zdefiniowany następujący formularz którego kod wygląda następująco:
<FORM NAME="form1">
Wiek: <INPUT TYPE="text" NAME="nazwa1" VALUE="0">
Identyfikator: <INPUT TYPE="text" NAME="nazwa2">
Data [dd/mm/rrrr]: <INPUT TYPE="text" NAME="nazwa3">
<INPUT TYPE="submit" NAME="ok" VALUE="Wyślij">
</FORM>
Moim celem byłoby wprowadzenie przez użytkownika w pola następujących wartości:
wiek - liczba maksymalnie 3 cyfrowa
identyfikator - alfanumeryk nie dłuszy niż 12 znaków
data - w formacie podanym w []
By zyskać większą pewność, że tak będzie spróbuję kontrolować wprowadzone dane. Do tego celu wykorzystam zdarzenie onSubmit obiektu form i do mojego formularza dodam odpowiedni kod, czyli:
wiek - liczba maksymalnie 3 cyfrowa
identyfikator - alfanumeryk nie dłuszy niż 12 znaków
data - w formacie podanym w []
By zyskać większą pewność, że tak będzie spróbuję kontrolować wprowadzone dane. Do tego celu wykorzystam zdarzenie onSubmit obiektu form i do mojego formularza dodam odpowiedni kod, czyli:
<FORM NAME="form1" onSubmit="return Validate();">
co spowoduje wywołanie funkcji Validate po naciśnięciu przycisku Wyślij. Jak widać funkcja Validate coś powinna zwracać. Może to być wartość true, czyli jeżeli formularz zawiera ACTION to wywoływany jest odpowiedni skrypt lub false i wtedy pozostajemy na stronie z fromularzem i nie wykona się żadna akcja.
Następnym krokiem powinno być utworzenie w JS funkcji Validate, która kontroluje pola i w zależności od ich poprawności zwraca true lub wyświetla komunikat o nieprawidłowościach w danych i zwraca false.
W celu uproszczenia i zuniwersalizowania tego procesu stworzyłem klasę TValidation, która zawiera kilka metod do kontroli danych oraz pozwala na bardzo eleganckie rozwiązanie tego problemu. Dla mojego formularza należałoby dodać następujący kod JS
Następnym krokiem powinno być utworzenie w JS funkcji Validate, która kontroluje pola i w zależności od ich poprawności zwraca true lub wyświetla komunikat o nieprawidłowościach w danych i zwraca false.
W celu uproszczenia i zuniwersalizowania tego procesu stworzyłem klasę TValidation, która zawiera kilka metod do kontroli danych oraz pozwala na bardzo eleganckie rozwiązanie tego problemu. Dla mojego formularza należałoby dodać następujący kod JS
<script language="JavaScript" src="tvalidation.js">
</script>
<script>
function Validate()
{
var v = new TValidation("form1");
v.AddItem("nazwa1", "Wiek musi byc wartością liczbową o max . długości 3 znaków", "vLength(v, 3) && Integer(v)");
v.AddItem("nazwa2", "Pole musi być wypełnione i nie może być dłuższe niż 12 znaków", "vLength(v, 12) && vRequired(v)");
v.AddItem("nazwa3", "Data musi być w formacie dd/mm/rrrr", "vDate(v)");
return v.Check();
}
</script>
Jak widać kod jest dość krótki i w miarę przejrzysty. Wszystkie czynności związane z kontrolą danych spoczywają na obiekcie v, który tworzę na bazie klasy TValidate podając NAME formularza, dla którego ma być wykonana kontrola.
Pola, które mają być sprawdzane specyfikujemy wywołując metodę AddItem z odpowiednimi parametrami. Weryfikacja poprawności pod względem podanych w AddItem warunków dokonuje się w metodzie Check. Jeżeli wszystko jest w porządku to zwracana jest wartość true, w przeciwnym wypadku wyświetla odpowiedni komunikat i zwraca false.
Teraz czas bliżej przyjrzeć się metodzie AddItem. Posiada ona następującą składnię:
Pola, które mają być sprawdzane specyfikujemy wywołując metodę AddItem z odpowiednimi parametrami. Weryfikacja poprawności pod względem podanych w AddItem warunków dokonuje się w metodzie Check. Jeżeli wszystko jest w porządku to zwracana jest wartość true, w przeciwnym wypadku wyświetla odpowiedni komunikat i zwraca false.
Teraz czas bliżej przyjrzeć się metodzie AddItem. Posiada ona następującą składnię:
AddItem(nazwa_pola, komunikat_w_wypadku_bledu, regula_poprawnosci)
Każdy z parametrów jest typu znakowego. Pierwsze dwa są na tyle jasne, że nie będę ich szczegółowo komentował. Dokładnie zajmę się trzecim parametrem. Jak widać na przykładzie ten parametr składa się z jednej lub wielu funkcji połączonych znakiem &&. Każda funkcja wywoływan jest ze zmienną wskazującą obiekt typu TValidate oraz opcjonalnie z innymi parametrami.
A oto lista możliwych do użycia funkcji kontroli:
A oto lista możliwych do użycia funkcji kontroli:
vLength(val, nLen)
Funkcja sprawdza, czy długość pola nie jest większa niż nLen.
vRequired(val)
Funkcja sprawdza, czy dane pole nie jest puste.
vIsInteger(val)
Sprawdzenie, czy wartość pola jest liczbą typu całkowitego.
vIsFloat(val)
Sprawdzenie, czy wartość pola jest liczbą typu rzeczywistego.
vDate(val, nFormat)
Funkcja kontroluje czy podany ciag znaków jest poprawną datą, można użyć trzech formatów zależnie od parametru nFormat: 0 - dd/mm/rrrr, 1 - mm/dd/rrrr, 2 - rrrr/mm/dd
Oczywiście klasę można rozbudowywać dodając np. nowe funkcje kontroli. Na pewno stanowi ona niezły wzorzec do dalszych własnych prac.
Kod źrodłowy znajduje się poniżej.
Kod źrodłowy znajduje się poniżej.
////////////
//
// Validation Library
//
// (c) Jacek Murawski, Kozienice 1999
//
// e-mail: jacek.murawski@elko.com.pl
// http:// www.chinasoft.com.pl
//
////////////
// funkcje sprawdzania poprawnosci danych nie nalezaca do
// zadnej klasy
// Dostepne funkcje:
//
// vLength(val, nLen)
// vRequired(val)
// vIsInteger(val)
// vIsFloat(val)
// vDate(val, nFormat)
// 0 - dd/mm/rrrr
// 1 - mm/dd/rrrr
// 2 - rrrr/mm/dd
//
// Do zrobienia:
//
// vEmail(val)
// vRangeInt(val, nFrom, nTo)
// vRangeFloat(val, nFrom, nTo)
//
// funkcja sprawdzajaca, czy wartosc pola nie jest dluzsza niz ...
function vLength(val, nLen)
{
if (val.length > nLen)
return false;
else
return true;
}
// funkcja sprawdza, czy wartosc pola > 0
function vRequired(val)
{
if (val.length < 1)
return false;
else
return true;
}
// sprawdzenie czy w polu liczba Integer
function vInteger(val)
{
var i = 0;
var is_ok = true;
var number = "+-0123456789";
if (number.indexOf(val.charAt(0)) == -1)
is_ok = false;
number = number.substring(2, 20);
for (i = 1; i < val.length; i++)
{
if (number.indexOf(val.charAt(i)) == -1)
is_ok = false;
}
return is_ok
}
// sprawdzenie, czy w polu liczba float
function vFloat(val)
{
var i = 0;
var is_ok = true;
var number = "+-0123456789.";
if (number.indexOf(val.charAt(0)) == -1)
is_ok = false;
number = number.substring(2, 20);
for (i = 1; i < val.length; i++)
{
if (number.indexOf(val.charAt(i)) == -1)
is_ok = false;
}
return is_ok;
}
// sprawdzenie czy w polu prawidlowa data
// 0 - dd/mm/rrrr
// 1 - mm/dd/rrrr
// 2 - rrrr/mm/dd
// 1234567890
function vDate(val, format)
{
var i = 0;
var is_ok = true;
var number = "0123456789";
var s;
if (format == null)
format = 0;
// sprawdzenie dlugosci
if (val.length != 10)
return false;
if (format == 0)
{
s_month = val.substring(0,2);
s_day = val.substring(3,5);
s_year = val.substring(6,10);
// separatory
if ((val.charAt(2) != "/") || (val.charAt(5) != "/"))
return false;
}
// dni
for (i = 0; i < 2; i++)
{
if (number.indexOf(s_day.charAt(i)) == -1)
is_ok = false;
}
if (is_ok)
nDay = parseInt(s_day);
else
return false;
// miesiace
for (i = 0; i < 2; i++)
{
if (number.indexOf(s_month.charAt(i)) == -1)
is_ok = false;
}
if (is_ok)
nMonth = parseInt(s_month);
else
return false;
// lata
for (i = 0; i < 4; i++)
{
if (number.indexOf(s_year.charAt(i)) == -1)
is_ok = false;
}
if (is_ok)
nYear = parseInt(s_year);
else
return false;
return is_ok
}
//////////////////////////////////////////////////////
//
// definicja klasy TValidation
//
//////////////////////////////////////////////////////
////////////////// Klasa TField /////////////////////
function TField()
{
this.Name = "";
this.Message = "";
this.isValid = false;
this.Code = "";
this.SetName = TField_SetName;
this.SetMessage = TField_SetMessage;
this.SetIsValid = TField_SetIsValid;
this.SetCode = TField_SetCode;
this.GetName = TField_GetName;
this.GetMessage = TField_GetMessage;
this.GetIsValid = TField_GetIsValid;
this.GetCode = TField_GetCode;
// sprawdzanie poprawnosci pola
this.Check = TField_Check;
}
function TField_SetName(cName)
{
this.Name = cName;
}
function TField_SetMessage(cMessage)
{
this.Message = cMessage;
}
function TField_SetIsValid(bIsValid)
{
this.isValid = bIsValid;
}
function TField_SetCode(cCode)
{
return this.Code = cCode;
}
function TField_GetName()
{
return this.Name;
}
function TField_GetMessage()
{
return this.Message;
}
function TField_GetIsValid()
{
return this.isValid;
}
function TField_GetCode()
{
return this.Code;
}
// sprawdzanie poprawnosci pola
function TField_Check(cForm)
{
var v = eval("document." + cForm + "." + this.Name + ".value");
this.isValid = eval(this.Code);
// ewentualna zmiana zawartosci pola
// if (!this.isValid)
// {
// cNew = v + "???";
// eval("document." + cForm + "." + this.Name + ".value = " + "\""+cNew+"\"");
// }
}
/////////////////// Klasa TListField ////////////////////
function TListField()
{
this.List = new Array(1);
this.Counter = 0;
this.Add = TListField_Add;
this.GetMsg = TListField_GetMsg;
this.IsValid = TListField_IsValid;
this.Check = TListField_Check;
this.Clear = TListField_Clear;
this.BuildMsg = TListField_BuildMsg;
}
// dodanie wiersz do listy pol
function TListField_Add(cName, cMsg, cCode)
{
var fld = new TField;
fld.SetName(cName);
fld.SetMessage(cMsg);
fld.SetIsValid(false);
fld.SetCode(cCode);
this.List[this.Counter] = fld;
this.Counter++;
}
// czyszczenie listy
function TListField_Clear()
{
this.Counter = 0;
}
// pobranie komunikatu
function TListField_GetMsg(nRow)
{
var fld = new TField;
fld = this.List[nRow];
return fld.GetMessage();
}
function TListField_IsValid(nRow)
{
var fld = new TField;
fld = this.List[nRow];
return fld.GetIsValid();
}
// sprawdzenie listy pol
function TListField_Check(cForm)
{
var fld = new TField;
var isOk = true;
for (i = 0; i < this.Counter; i++)
{
fld = this.List[i];
fld.Check(cForm);
this.List[i] = fld;
if (!fld.GetIsValid())
isOk = false;
}
return isOk;
}
// budowanie komunikatu bledu
function TListField_BuildMsg()
{
var fld = new TField;
var cMsg = ""
for (i = 0; i < this.Counter; i++)
{
fld = this.List[i];
if (!fld.GetIsValid())
{
cMsg = cMsg + fld.GetMessage() + "\n";
// window.alert(cMsg);
}
}
return cMsg;
}
/////////////////////// klasa TValidation ////////////////////
function TValidation(cForm)
{
this.FormName = cForm;
this.List = new TListField();
this.AddItem = TValidation_AddItem;
this.Check = TValidation_Check;
this.MessageWin = TValidation_MessageWin;
}
// dodanie elementu
function TValidation_AddItem(cName, cMsg, cCode)
{
this.List.Add(cName, cMsg, cCode);
}
// sprawdzenie formularza
function TValidation_Check()
{
if (this.List.Check(this.FormName))
return true;
else
{
this.MessageWin();
return false;
}
}
// jezeli weryfikacja niepoprawna to
// wyswietlenie okna z komunikatem bledu
function TValidation_MessageWin()
{
cMsg = "Dane niepoprawne:\n";
cMsg2 = this.List.BuildMsg();
window.alert(cMsg+cMsg2);
}